feat(algorithms, intervals): count minimum non-overlapping intervals#143
Conversation
📝 WalkthroughWalkthroughThis PR introduces a complete solution for the "Count Non-Overlapping Intervals" problem, including algorithm implementation with two variants, comprehensive documentation, and parameterized tests. It also updates the insert_interval documentation with detailed phase-based solution explanation. Changes
Poem
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (5)
DIRECTORY.md (1)
140-141: Indentation style matches codebase convention but diverges from strict Markdown spec.Lines 140–141 use 4 and 6 spaces respectively, consistent with all other entries in the Intervals section. However, markdownlint expects 2 and 4 spaces per MD007. Since the entire file follows the 4/6 convention, this is not a new inconsistency, but consider aligning with standard Markdown guidelines in a future refactor.
algorithms/intervals/count_non_overlapping_intervals/README.md (1)
56-60: Minor formatting and clarity improvements needed in complexity analysis.Line 56:
O(n * logn)should use consistent spacing:O(n * log n).Line 60 states "We only initialize two extra variables" but doesn't explicitly complete the notation. Suggest: "O(1) where we only initialize two extra variables..." for clarity and consistency with the Time Complexity section format.
algorithms/intervals/count_non_overlapping_intervals/__init__.py (2)
4-23: Consider adding input validation for interval structure.The function assumes each interval contains exactly two elements
[start, end]and thatstart <= end. Invalid inputs like[[1]],[[1, 2, 3]], or[[5, 1]]could causeIndexErroror produce incorrect results.Consider adding validation at the start of the function:
🔎 Suggested input validation
def count_min_non_overlapping_intervals(intervals: List[List[int]]) -> int: """ Counts the minimum number of intervals that must be removed to make the intervals non-overlapping. Modifies the input list in place Args: intervals (List[List[int]]): The intervals to check Returns: int: number of intervals to remove """ if not intervals: return 0 + # Validate interval structure + for interval in intervals: + if len(interval) != 2: + raise ValueError(f"Each interval must have exactly 2 elements, got {len(interval)}") + if interval[0] > interval[1]: + raise ValueError(f"Interval start must be <= end, got {interval}") intervals.sort(key=lambda x: x[1]) end = intervals[0][1] count = 1 for i in range(1, len(intervals)): # Non-overlapping interval found if intervals[i][0] >= end: end = intervals[i][1] count += 1 return len(intervals) - count
26-50: Consider adding input validation for interval structure.Similar to the first implementation, this function assumes well-formed intervals. Apply the same validation logic to ensure robustness.
🔎 Suggested input validation
def count_min_non_overlapping_intervals_2(intervals: List[List[int]]) -> int: """ Counts the minimum number of intervals that must be removed to make the intervals non-overlapping. Does not modify the input list in place, this instead uses a sorted copy of the input intervals Args: intervals (List[List[int]]): The intervals to check Returns: int: number of intervals to remove """ if not intervals: return 0 + # Validate interval structure + for interval in intervals: + if len(interval) != 2: + raise ValueError(f"Each interval must have exactly 2 elements, got {len(interval)}") + if interval[0] > interval[1]: + raise ValueError(f"Interval start must be <= end, got {interval}") sorted_intervals = sorted(intervals, key=lambda x: x[1]) end = sorted_intervals[0][1] count = 1 for current_interval in sorted_intervals[1:]: current_interval_start, current_interval_end = current_interval # Non-overlapping interval found if current_interval_start >= end: end = current_interval_end count += 1 return len(sorted_intervals) - countalgorithms/intervals/count_non_overlapping_intervals/test_count_min_non_overlapping_intervals.py (1)
10-19: Consider adding edge case test coverage.The test cases cover various overlapping scenarios well, but could benefit from additional edge cases:
- Single interval:
[[1, 5]]→ expected0- Empty list:
[]→ expected0(implementation handles this)- Negative intervals:
[[-5, -1], [-3, 0], [1, 3]]- Large gaps:
[[1, 2], [100, 200]]→ expected0🔎 Suggested additional test cases
COUNT_NON_OVERLAPPING_INTERVALS_TEST_CASES = [ ([[1, 3], [5, 8], [4, 10], [11, 13]], 1), ([[1, 2], [2, 3], [3, 4], [1, 3]], 1), ([[1, 2], [1, 2], [1, 2]], 2), ([[1, 2], [2, 3]], 0), ([[1, 5], [2, 3], [3, 4], [4, 6]], 1), ([[1, 3], [3, 5], [4, 6], [5, 7]], 1), ([[1, 3], [2, 4], [3, 5]], 1), ([[0, 2], [1, 3], [2, 4], [3, 5], [4, 6]], 2), + # Edge cases + ([[1, 5]], 0), # Single interval + ([], 0), # Empty list + ([[-5, -1], [-3, 0], [1, 3]], 1), # Negative intervals + ([[1, 2], [100, 200]], 0), # Large gaps ]
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (20)
algorithms/intervals/count_non_overlapping_intervals/images/examples/count_non_overlapping_intervals_example_1.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_1.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_2.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_3.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_4.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_5.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_6.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_7.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_8.pngis excluded by!**/*.pngalgorithms/intervals/count_non_overlapping_intervals/images/solutions/count_non_overlapping_intervals_solution_9.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_1.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_10.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_2.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_3.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_4.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_5.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_6.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_7.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_8.pngis excluded by!**/*.pngalgorithms/intervals/insert_interval/images/solutions/insert_interval_solution_9.pngis excluded by!**/*.png
📒 Files selected for processing (5)
DIRECTORY.mdalgorithms/intervals/count_non_overlapping_intervals/README.mdalgorithms/intervals/count_non_overlapping_intervals/__init__.pyalgorithms/intervals/count_non_overlapping_intervals/test_count_min_non_overlapping_intervals.pyalgorithms/intervals/insert_interval/README.md
🧰 Additional context used
🧬 Code graph analysis (1)
algorithms/intervals/count_non_overlapping_intervals/test_count_min_non_overlapping_intervals.py (1)
algorithms/intervals/count_non_overlapping_intervals/__init__.py (2)
count_min_non_overlapping_intervals(4-23)count_min_non_overlapping_intervals_2(26-50)
🪛 LanguageTool
algorithms/intervals/count_non_overlapping_intervals/README.md
[grammar] ~56-~56: Ensure spelling is correct
Context: ...y Analysis #### Time Complexity O(n * logn) where n is the number of intervals. The...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
algorithms/intervals/insert_interval/README.md
[style] ~63-~63: Using many exclamation marks might seem excessive (in this case: 4 exclamation marks for a text that’s 2680 characters long)
Context: ...lutions/insert_interval_solution_8.png) 
🪛 markdownlint-cli2 (0.18.1)
DIRECTORY.md
140-140: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
141-141: Unordered list indentation
Expected: 4; Actual: 6
(MD007, ul-indent)
algorithms/intervals/insert_interval/README.md
38-38: Reference links and images should use a label that is defined
Missing link or image reference definition: "1"
(MD052, reference-links-images)
47-47: Reference links and images should use a label that is defined
Missing link or image reference definition: "0"
(MD052, reference-links-images)
🔇 Additional comments (3)
algorithms/intervals/insert_interval/README.md (1)
26-75: Comprehensive solution writeup enhances interval insertion documentation.The three-phase explanation (lines 26–62) with visual aids clearly describes the algorithm. Complexity analysis (lines 67–75) correctly identifies O(n) time and O(n) space.
Note: Markdownlint warnings for reference links (MD052) are false positives—they flag array indexing syntax
[i][0]and[i][1]as markdown references. Similarly, the exclamation marks flagged by LanguageTool are part of image alt text syntax, not excessive punctuation.algorithms/intervals/count_non_overlapping_intervals/test_count_min_non_overlapping_intervals.py (2)
27-28: Excellent use of deepcopy for the mutating function test.The
deepcopyensures that each parameterized test case starts with fresh data, preventing the in-place sort from affecting subsequent test iterations.
4-4: No action needed. Version 0.9.0 of parameterized is the current latest release and has no known security vulnerabilities.
Describe your change:
Contains algorithm to count minimum number of intervals to remove from a given list of intervals that will make the intervals non-overlapping
Also:
Checklist:
Fixes: #{$ISSUE_NO}.Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.